/*
 * Antonio Canabrava Fraideinberze 7152292
 * Lucas Avelino Sodre Santos      7239086
 * Pedro Rael Garcia               7153021
 */

/*
 * This file process the big file, a.k.a wikipedia.txt
 *
 * It find each palindrome inside the text and calculates if it is prime
 *
 * This algorithm uses AVL tree in order to not repeat the same palindrome
 *  insede the output file, a.k.a. palindromes.
 *
 * The palindromes has a minimum size defined by the group with the length of 2,
 * in other words, it just doesn't get any letter and says that it's a palindrome.
 */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "sieve.h"
#include "avl.h"

#define MAX 1000

int min(int a, int b);
int max(int a, int b);
int palindrome(char *word, int len);

int
main(int argc, char *argv[])
{
    FILE *ifp;
    FILE *ofp;
    char *buf;
    char word[MAX];
    char sieve[LAST_PRIME + 1];
    int i;
    int res;
    int sum;
    int f_size;
    node *t = NULL;

    if(argc != 2)
    {
        printf("Usage: $big [file]");
        exit(1);
    }

    printf("Carregando arquivo...\n");
    ifp = fopen(argv[1], "r");

    if(ifp == NULL)
    {
        fprintf(stderr, "Could not open the file. Exiting.\n");
        exit(1);
    }

    ofp = fopen("palindromes", "w");

    if(ofp == NULL)
    {
        fprintf(stderr, "Could not create the file. Exiting.\n");
        exit(1);
    }

    printf("Calculando o Crivo de Eratosthenes...\n");
    calc_sieve(sieve);
    fseek(ifp, 0, SEEK_END);
    f_size = ftell(ifp);
    rewind(ifp);
    buf = (char *) malloc(f_size * sizeof(char));

    if(buf == NULL)
    {
        fprintf(stderr, "Could not allocate memory. Exiting.\n");
        exit(1);
    }

    res = fread(buf, 1, f_size, ifp);

    if(res != f_size)
    {
        fprintf(stderr, "Could not load the file. Exiting.\n");
        exit(1);
    }

    printf("Montando a árvore AVL com os palíndromos...\n");
    res = 0;

    while(res <= f_size)
    {
        while(!isalnum(buf[res])) res++;

        i = 0;
        sum = 0;

        while(isalnum(buf[res]))
        {
            word[i] = tolower(buf[res]);
            sum += word[i];
            res++;
            i++;
        }

        word[i] = '\0';

        if(i > 1 && i == palindrome(word, i) && (find(word, t) == NULL))
        {
            fprintf(ofp, "Word: %s - Len: %d - Sum: %d - Prime: %c\n",
                    word, i, sum, sieve[sum]);
            t = insert(word, t);
        }
    }

    printf("Limpando os buffers...\n");
    free(buf);
    fclose(ifp);
    fclose(ofp);
    clear(t);
    return 0;
}

int min(int a, int b)
{
    return a > b ? b : a;
}
int max(int a, int b)
{
    return a > b ? a : b;
}

int
palindrome(char *word, int len)
{
    int i;
    int res = 0;

    for(i = 0; i < len; i++)
        if(word[i] == word[len - i - 1])
            res++;

    return res;
}

